/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package za.co.pas.spaceandtime.data;

import za.co.pas.business.data.Address;
import za.co.pas.business.data.GenericData;
import za.co.pas.business.data.Company;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

/**
 *
 * @author alabuschagne
 */
@Entity
public class Building extends GenericData implements Serializable
{

    private Company company;
    private static final long serialVersionUID = 1L;
    private List<Room> rooms = new LinkedList<Room>();
    private Address streetAddress;
    private Address postalAddress;
    private Boolean enabled = Boolean.FALSE;
    
    @Override
    public int hashCode()
    {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object object)
    {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Building))
        {
            return false;
        }
        Building other = (Building) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)))
        {
            return false;
        }
        return true;
    }

    /**
     * @return the rooms
     */
    @OneToMany(cascade = CascadeType.ALL)
    public List<Room> getRooms()
    {
        return rooms;
    }

    /**
     * @param rooms the rooms to set
     */
    public void setRooms(List<Room> rooms)
    {
        this.rooms = rooms;
    }

    @ManyToOne(cascade = CascadeType.ALL)
    public Company getCompany()
    {
        return company;
    }

    public void setCompany(Company company)
    {
        this.company = company;
    }

    /**
     * @return the streetAddress
     */
    @OneToOne(cascade = CascadeType.ALL)
    public Address getStreetAddress()
    {
        return streetAddress;
    }

    /**
     * @param streetAddress the streetAddress to set
     */
    public void setStreetAddress(Address streetAddress)
    {
        this.streetAddress = streetAddress;
    }

    /**
     * @return the postalAddress
     */
    @OneToOne(cascade = CascadeType.ALL)
    public Address getPostalAddress()
    {
        return postalAddress;
    }

    /**
     * @param postalAddress the postalAddress to set
     */
    public void setPostalAddress(Address postalAddress)
    {
        this.postalAddress = postalAddress;
    }

    public boolean check(Building otherBuilding)
    {
        if (!super.check(otherBuilding))
        {
            return false;
        }
        else if ((streetAddress == null) && (otherBuilding.getStreetAddress() != null))
        {
            return false;
        }
        else if ((streetAddress != null) && (!streetAddress.check(otherBuilding.getStreetAddress())))
        {
            return false;
        }
        else if ((postalAddress == null) && (otherBuilding.getPostalAddress() != null))
        {
            return false;
        }
        else if ((postalAddress != null) && (!postalAddress.check(otherBuilding.getPostalAddress())))
        {
            return false;
        }
        else if ((rooms == null) && (otherBuilding.getRooms() != null))
        {
            return false;
        }
        else if (rooms != null)
        {
            if (otherBuilding.getRooms() == null)
            {
                return false;
            }
            if (rooms.size() != otherBuilding.getRooms().size())
            {
                return false;
            }
            ListIterator<Room> itMe = rooms.listIterator();
            while (itMe.hasNext())
            {
                Room rMe = itMe.next();
                boolean found = false;
                ListIterator<Room> itOther = otherBuilding.getRooms().listIterator();
                while (itOther.hasNext())
                {
                    if (rMe.check(itOther.next()))
                    {
                        found = true;
                        break;//out of inner loop
                    }
                }
                if (!found)
                {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Remember to set company on top level
     * @return
     */
    @Override
    public Building clone()
    {
        Building newBuilding = new Building();
        newBuilding.setId(id);
        newBuilding.setDescription(description);
        newBuilding.setName(name);
        newBuilding.setEnabled(enabled);
        if (postalAddress != null)
        {
            newBuilding.setPostalAddress(postalAddress.clone());
        }
        if (streetAddress != null)
        {
            newBuilding.setStreetAddress(streetAddress.clone());
        }
        if (rooms != null)
        {
            List<Room> rs = new LinkedList<Room>();
            ListIterator<Room> it = rooms.listIterator();
            while (it.hasNext())
            {
                rs.add(it.next().clone());
            }
            newBuilding.setRooms(rs);
        }
        return newBuilding;
    }

    

    /**
     * @return the enabled
     */
    public Boolean getEnabled()
    {
        return enabled;
    }

    /**
     * @param enabled the enabled to set
     */
    public void setEnabled(Boolean enabled)
    {
        this.enabled = enabled;
    }

    public void addRoom(Room room)
    {
        if(rooms == null)
        {
            rooms = new LinkedList<Room>();
        }
        rooms.add(room);
    }

    
}
